home *** CD-ROM | disk | FTP | other *** search
/ Chip 2006 June (Extra) / CHIP 2006-06.3.iso / program / opensource / Inkscape-0.43-2.win32.exe / share / extensions / embed_raster_in_svg.pl < prev    next >
Encoding:
Perl Script  |  2005-02-06  |  4.2 KB  |  123 lines

  1. #!/usr/bin/perl
  2.  
  3. #----------------------------------------------------------------------------------------------
  4. # embed_raster_in_svg
  5. # B. Crowell, crowellXX at lightandmatter.com (replace XX with last two digits of current year)
  6. # (c) 2004 B. Crowell
  7. # This program is available under version 2 of the GPL License, http://www.gnu.org/copyleft/gpl.html,
  8. # or, at your option, under the same license as Perl.
  9. # For information about this program, scroll down in the source code, or invoke the program
  10. # without any command-line arguments.
  11. #----------------------------------------------------------------------------------------------
  12.  
  13. use strict;
  14.  
  15. use MIME::Base64;
  16. use Cwd;
  17. use File::Basename;
  18.  
  19. my $info = <<'INFO';
  20.  usage:
  21.     embed_raster_in_svg foo.svg
  22.  Looks through the svg file for raster images that are given as links, rather than
  23.  being embedded, and embeds them in the file. The links must be local URIs, and if
  24.  they're relative, they must be relative to the directory where the svg file is located.
  25.  Starting with Inkscape 0.41, Inkscape can
  26.  handle embedded raster images as well as ones that are linked to (?).
  27.  Typical input looks like this:
  28.   <image
  29.      xlink:href="beer.jpg"
  30.      sodipodi:absref="/home/bcrowell/Documents/programming/embed_raster_in_svg/tests/beer.jpg"
  31.      width="202.50000"
  32.      height="537.00000"
  33.      id="image1084"
  34.      x="281.67480"
  35.      y="242.58502" />
  36.   The output should look like this:
  37.    <image
  38.      width="202.50000"
  39.      height="537.00000"
  40.      id="image1084"
  41.      x="281.67480"
  42.      y="242.58502"
  43.      xlink:href="data:;base64,...
  44.   The SVG standard only allows the <image> tag to refer to data of type png, jpg, or svg,
  45.   and this script only handles png or jpg.
  46. INFO
  47.  
  48. undef $/; # slurp whole file
  49.  
  50. my $svg = $ARGV[0];
  51.  
  52. if (!$svg) {
  53.   print $info;
  54.   exit;
  55. }
  56.  
  57. die "input file $svg not found" if ! -e $svg;
  58. die "input file $svg not readable" if ! -r $svg;
  59.  
  60. open(FILE,"<$svg") or die "error opening file $svg for input, $!";
  61. my $data = <FILE>;
  62. close FILE;
  63.  
  64. chdir dirname(Cwd::realpath($svg)); # so from now on, we can open raster files if they're relative to this directory
  65.  
  66.  
  67. # The file is now in memory.
  68. # First we go once through it and (1) find out if there are indeed any links to raster images,
  69. # (2) rearrange things a little so that the (lengthy) base64 data will be the last attribute of the
  70. # image tag.
  71.  
  72. my $n = 0;
  73. my @raster_files = ();
  74. $data =~
  75.   s@\<image\s+((?:(?:\w|\:)+\=\"[^"]*\"\s*)*)xlink\:href=\"([^"]+)\"\s*((?:(?:\w|:)+\=\"[^"]*\"\s*)*)\/>@<imageHOBBITSES $1 $3 ITHURTSUS\"$2\"MYPRECIOUSS />@g;
  76. while ($data=~m@<imageHOBBITSES\s*(?:(?:(?:\w|\:)+\=\"[^"]*\"\s*)*)ITHURTSUS\"([^"]+)\"MYPRECIOUSS />@g) {
  77.   my $raster = $1;
  78.   die "error, raster filename $raster contains a double quote" if $raster=~m/\"/;
  79.   if (!($raster=~m/data\:\;/)) {
  80.     ++$n;
  81.     push @raster_files,$raster;
  82.   }
  83. }
  84.  
  85. if ($n==0) {
  86.   print "no embedded jpgs found in file $svg\n";
  87.   exit;
  88. }
  89.  
  90.  
  91. # Eliminate sodipodi:absref attributes. If these are present, Inkscape looks for the linked
  92. # file, and ignores the embedded data. Also, get rid of those nasty hobbitses.
  93. $data=~s@(<image)HOBBITSES\s*((?:(?:\w|\:)+\=\"[^"]*\"\s*)*)sodipodi\:absref\=\"[^"]+\"\s*((:?(?:\w|\:)+\=\"[^"]*\"\s*)*ITHURTSUS)@$1 $2 $3@g;
  94. $data=~s@(<image)HOBBITSES@$1@g;
  95.  
  96.  
  97. # Now embed the data:
  98.  
  99. foreach my $raster(@raster_files) {
  100.   die "file $raster not found relative to directory ".getcwd() if ! -e $raster;
  101.   die "file $raster is nor readable" if ! -r $raster;
  102.   open(RASTER,"<$raster") or die "error opening file $raster for input, $!";
  103.   my $raster_data = <RASTER>;
  104.   close RASTER;
  105.   my $type = '';
  106.   $type='image/png' if $raster_data=~m/^\x{89}PNG/;
  107.   $type='image/jpg' if $raster_data=~m/^\x{ff}\x{d8}/;
  108.   die "file $raster does not appear to be of type PNG or JPG" unless $type;
  109.   my $raster_data_base64 = encode_base64($raster_data);
  110.   ($data =~ s@ITHURTSUS\"$raster\"MYPRECIOUSS@\n     xlink:href=\"data\:$type\;base64,$raster_data_base64\"@) or die "error embedding data for $raster";
  111.   print "embedded raster file $raster, $type\n";
  112. }
  113. my $bak = "$svg.bak";
  114. rename $svg,$bak or die "error renaming file $svg to $bak, $!";
  115. open(FILE,">$svg") or die "error creating new version of file $svg for output, $!";
  116. print FILE $data;
  117. close FILE;
  118.  
  119.  
  120.  
  121.  
  122.  
  123.